package cn.com.generaldata.os.service.indicator_evaluation.industry_collect_analysis;

import org.apache.commons.lang3.Validate;
import org.nutz.dao.sql.Criteria;

import cn.com.generaldata.jsme_indicator_system.entity.IndicatorEvaluation;
import cn.com.generaldata.jsme_indicator_system.util.Constants;
import cn.com.generaldata.os.service.indicator_constant.ProvinceIndicatorConstant;
import cn.com.generaldata.os.service.indicator_evaluation.IndicatorEvaluationCalculateService;
import cn.com.generaldata.os.util.BeanMapper;
import cn.com.generaldata.os.vo.IndicatorAccountVO;

/**
 * 主要海洋产业产业地理集中指数指标计算类.
 */
public class MajorMarineIndustryEGExponentCalculateService extends
		IndicatorEvaluationCalculateService {

	private String addValueOfMajorMarineIndustryName = ProvinceIndicatorConstant.MAJOR_MARINE_ADDVALUE_NAME;

	@Override
	protected Double calculate(IndicatorEvaluation indicator,
			IndicatorAccountVO indicatorAccountVO) {
		Double result = Double.valueOf(0);
		if (indicator.getSection() == Constants.INDICATOR_LEVEL_PROVINCE) {
			result = calculateProvinceResult(indicator, indicatorAccountVO);
		} else if (indicator.getSection() == Constants.INDICATOR_LEVEL_CITY) {
			// 市指标没确定先保留
		}
		return result;

	}

	/**
	 * 计算省级的H指数
	 * 
	 * @param indicatorAccountVO
	 * @return
	 */
	private Double calculateProvinceResult(IndicatorEvaluation indicator,
			IndicatorAccountVO indicatorAccountVO) {

		Double industryPropor = getIndustryPropor(indicator, indicatorAccountVO);

		Double HExponent = getProvinceHGExponent(indicator, indicatorAccountVO,
				"赫芬达尔-赫希曼指数");
		Double GExponent = getProvinceHGExponent(indicator, indicatorAccountVO,
				"空间基尼系数");

		Double numerator = GExponent - (1 - industryPropor) * HExponent;
		Double denominator = (1 - industryPropor) * (1 - HExponent);
		return numerator / denominator;
	}

	/**
	 * 获取省级的HG指标
	 * 
	 * @param indicator
	 * @param indicatorAccountVO
	 * @return
	 */
	private Double getProvinceHGExponent(IndicatorEvaluation indicator,
			IndicatorAccountVO indicatorAccountVO, String indicatorNameSuffix) {
		String indicatorName = ProvinceIndicatorConstant.MAJOR_MARINE_INDUSTRY_ADD_VALUE_MAP
				.get(indicator.getIndustryCode());
		indicatorName += indicatorNameSuffix;

		Integer indicatorId = getIndicatorEvaluationId(indicatorName, indicatorAccountVO.getAreaId());
		Criteria cri = getIndicatorDataCri(indicatorAccountVO, indicatorAccountVO.getYear(), indicatorId);

		Double result = getEvaluationIndicatorValue(cri);
		Validate.isTrue(result != null);
		return result;
	}

	/**
	 * 获取市海洋产业增加值占主要海洋产业增加值比重平方和
	 * 
	 * @param indicator
	 * @param indicatorAccountVO
	 * @return
	 */
	private Double getIndustryPropor(IndicatorEvaluation indicator,
			IndicatorAccountVO indicatorAccountVO) {
		Double result = Double.valueOf("0");
		for (String cityId : ProvinceIndicatorConstant.CITYS) {
			IndicatorAccountVO vo = BeanMapper.map(indicatorAccountVO,
					IndicatorAccountVO.class);
			vo.setAreaId(cityId);

			Double cityAddValueOfIndustry = getCityAddValueOfIndustry(vo,
					indicator);
			Double addValueOfMajorMarineIndustry = getCityAddValueOfMajorMarineIndustry(vo);
			Double addValueOfMajorMarineProportion = null;
			if (cityAddValueOfIndustry == null || addValueOfMajorMarineIndustry == null) {
				continue;
			}
			addValueOfMajorMarineProportion = cityAddValueOfIndustry / addValueOfMajorMarineIndustry;

			result += Math.pow(addValueOfMajorMarineProportion, 2);
		}
		return result;
	}

	/**
	 * 获得市级十个主要海洋产业的增加值
	 * 
	 * @param indicatorAccountVO
	 * @param indicator
	 * @return
	 */
	private Double getCityAddValueOfIndustry(
			IndicatorAccountVO indicatorAccountVO, IndicatorEvaluation indicator) {
		String industryName = ProvinceIndicatorConstant.MAJOR_MARINE_INDUSTRY_ADD_VALUE_MAP
				.get(indicator.getIndustryCode());
		Double inputOrAccountingIndicatorValue = getInputOrAccountingIndicatorValue(indicatorAccountVO,
				indicatorAccountVO.getYear(), industryName);
		// Validate.isTrue(inputOrAccountingIndicatorValue != null);
		return inputOrAccountingIndicatorValue;
	}

	/**
	 * 获得市级主要海洋产业的增加值
	 * 
	 * @param indicatorAccountVO
	 * @param indicator
	 * @return
	 */
	private Double getCityAddValueOfMajorMarineIndustry(
			IndicatorAccountVO indicatorAccountVO) {

		Double inputOrAccountingIndicatorValue = getInputOrAccountingIndicatorValue(indicatorAccountVO,
				indicatorAccountVO.getYear(), addValueOfMajorMarineIndustryName);
		// Validate.isTrue(inputOrAccountingIndicatorValue != null);
		return inputOrAccountingIndicatorValue;
	}

}
